package com.polaris.live.ui.luckybag.fragment

import android.os.Bundle
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.blankj.utilcode.util.StringUtils
import com.polaris.live.R
import com.polaris.live.adapter.luckybag.LuckyBagMessageAdapter
import com.polaris.live.common.cacha.UserManager
import com.polaris.live.common.constant.CommonConst
import com.polaris.live.common.ext.setOnSingleClickListener
import com.polaris.live.common.mvvm.base2.BaseVbFragment
import com.polaris.live.common.network.parseState
import com.polaris.live.common.util.DebounceHelper
import com.polaris.live.common.util.JsonUtils
import com.polaris.live.common.util.ToastGravity
import com.polaris.live.databinding.FragmentLuckyBagBinding
import com.polaris.live.dialog.luckybag.LuckyBagDetailDialog
import com.polaris.live.im.sfs.bean.pusher.LuckyBagNoticeMessage
import com.polaris.live.popup.GlobalPopupManager
import com.polaris.live.resp.back_resp.luckybag.LuckyBagDetailResp
import com.polaris.live.resp.back_resp.luckybag.LuckyBagMessageResp
import com.polaris.live.translation.R.string
import com.polaris.live.utils.CommonUtils.toBoolean
import com.polaris.live.utils.RecyclerUtils.getFirstPosition
import com.polaris.live.utils.XPopupUtils
import com.polaris.live.viewmodel.luckybag.LuckyBagViewModel
import com.polaris.live.widget.refresh.ListOperator
import com.polaris.live.widget.refresh.LoadStateView
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

/**
 * 福袋消息界面
 *
 * @author Created by lucas on 2024/6/11 02:12
 * @since 1.0.0
 */
class LuckyBagMessageFragment : BaseVbFragment<LuckyBagViewModel, FragmentLuckyBagBinding>() {

    private val mAdapter by lazy { LuckyBagMessageAdapter() }
    private var mScrollState = RecyclerView.SCROLL_STATE_IDLE

    private val excludeSet = mutableSetOf<Long>()

    override fun initView(savedInstanceState: Bundle?) {
        initView()
        initObserver()
        initListener()
    }

    private fun initView() {
        EventBus.getDefault().register(this)

        arguments?.getLong("liveId").let {
            mViewModel.mLiveId = it
        }
        arguments?.getInt("type")?.let {
            when (it) {
                CLAIMABLE -> mViewModel.mOnlyUncompleted = true
                CHAT -> mViewModel.mOnlyMessage = true
            }
        }

        mBinding.rvRecycler.apply {
            layoutManager = LinearLayoutManager(requireContext()).apply {
                reverseLayout = true
                stackFromEnd = true
            }
            itemAnimator = null
            adapter = mAdapter
        }
        mBinding.lvLoading.setEmptyTip(
            R.drawable.salalogo,
            StringUtils.getString(string.no_hava_data)
        )
    }

    private fun initObserver() {
        mViewModel.mListLiveData.observe(this) { state ->
            parseState(state, { resp ->
                mBinding.rvRecycler.visibility = View.VISIBLE

                mAdapter.loadMoreModule.isEnableLoadMore = false

                val finalList = resp.list.filter { excludeSet.add(it.messageId) }
                if (mViewModel.mPageIndex == 0) {
                    mAdapter.addData(finalList)

                    if (mAdapter.data.isEmpty()) {
                        mBinding.lvLoading.setState(LoadStateView.STATE_EMPTY)
                    } else {
                        mBinding.lvLoading.setState(LoadStateView.STATE_SUCCESS)
                    }

                    mBinding.rvRecycler.scrollToPosition(0)
                } else {
                    mAdapter.loadMoreModule.loadMoreComplete()

                    mAdapter.addData(finalList)
                }

                mBinding.rvRecycler.post {
                    mAdapter.loadMoreModule.isEnableLoadMore = resp.hasMore
                }
            }, {
                if (mViewModel.mPageIndex == 0) {
                    mBinding.lvLoading.setState(LoadStateView.STATE_ERROR, it.errorMsg)
                    mAdapter.loadMoreModule.isEnableLoadMore = false
                } else {
                    mAdapter.loadMoreModule.loadMoreFail()

                    ToastGravity.showGravity(it.errorMsg)
                }
            })
        }
        mViewModel.mNoticeMessageLiveData.observe(this) {
            if (!excludeSet.add(it.messageId)) {
                return@observe
            }
            var isKeepShow = false
            //当这个是领取消息 并且 我是领取人才可以
            val isMeReceive =
                it.messageType == CommonConst.LuckyBagMessageType.RECEIVE && it.getPromptMessage()?.receiveUserId == UserManager.getUserId()
            //当这个是红包消息 并且 不是我发的红包才可以
            val luckyBagMessage =
                it.messageType == CommonConst.LuckyBagMessageType.LUCKY_BAG && it.getBagMessage()?.userBasic?.userId != UserManager.getUserId()
            if (mViewModel.mOnlyUncompleted && (luckyBagMessage || isMeReceive)) {
                //当mOnlyUncompleted等于true 并且 messageType是领取福袋消息 并且 是别人发的 就代表现在是仅领取福袋消息
                isKeepShow = true
            } else if (mViewModel.mOnlyMessage == true && it.messageType == CommonConst.LuckyBagMessageType.LUCKY_CHAT) {
                //mOnlyMessage 等于 true 并且 messageType 是福袋聊天消息 就代表当前页面是是仅聊天消息
                isKeepShow = true
            } else if (!mViewModel.mOnlyUncompleted && mViewModel.mOnlyMessage == null) {
                //如果mOnlyUncompleted是false   mOnlyMessage 是空的就代表当前是领取全部消息
                isKeepShow = true
            }
            //全部或者只显示未领取的福袋，并且是别人发的
            if (isKeepShow) {
                val position = mBinding.rvRecycler.getFirstPosition() ?: 0
                val isScrollBottom = mScrollState == RecyclerView.SCROLL_STATE_IDLE && position < 2

                mAdapter.addData(0, it)

                //之前可能为空，现在有了需要显示数据
                mBinding.lvLoading.setState(LoadStateView.STATE_SUCCESS)
                if (isScrollBottom) {
                    mBinding.rvRecycler.scrollToPosition(0)
                }

                if (!isScrollBottom && it.messageType == CommonConst.LuckyBagMessageType.LUCKY_BAG
                    && it.userId != UserManager.getUserId()
                ) {
                    mBinding.llGoTo.visibility = View.VISIBLE
                }
            }

            //可能是领取了，需要更新状态
            updateState(it)
        }
        mViewModel.mReceiveLiveData.observe(this) { bean ->
            val resp = bean.resp
            if (resp.isSuccess()) {
                resp.result?.let {
                    updateState(it)
                    XPopupUtils.showPopup(
                        LuckyBagDetailDialog(requireContext(), it, mViewModel, true),
                        { hasShadowBg(true) },
                        lifecycle = lifecycle
                    )
                }
            } else {
                when (resp.code) {
                    //领取红包不需要展示Toast
                    CommonConst.ErrorCode.SENDGIFT -> {
                        GlobalPopupManager.showRechargePopup(
                            requireContext(),
                            mViewModel,
                            isNeedBottom = true,
                            luckyBagCoin = bean.coins
                        )
                    }

                    CommonConst.ErrorCode.LUCKY_BAG_COMPLETED -> {
                        updateState(bean.luckyBagId, null, CommonConst.LuckyBagStatus.COMPLETED)
                        ToastGravity.showGravity(resp.errorMessage)
                    }

                    CommonConst.ErrorCode.LUCKY_BAG_EXPIRED -> {
                        updateState(bean.luckyBagId, null, CommonConst.LuckyBagStatus.EXPIRED)
                        ToastGravity.showGravity(resp.errorMessage)
                    }

                    else -> ToastGravity.showGravity(resp.errorMessage)
                }

            }
        }
        mViewModel.mDetailLuckyBagLiveData.observe(this) { state ->
            parseState(state, {
                //只有自己会查看
                updateState(it.luckyBagId, null, it.status)

                XPopupUtils.showPopup(
                    LuckyBagDetailDialog(requireContext(), it, mViewModel),
                    { hasShadowBg(true) },
                    lifecycle = lifecycle
                )
            }, {
                ToastGravity.showGravity(it.errorMsg)
            })
        }
    }

    private fun initListener() {
        mAdapter.loadMoreModule.loadMoreView = ListOperator.adapterLoadMoreView
        mAdapter.loadMoreModule.preLoadNumber = 2
        mAdapter.loadMoreModule.setOnLoadMoreListener {
            mViewModel.onLoadMore()
        }

        mAdapter.setOnItemChildClickListener { _, v, position ->
            DebounceHelper.singleClick {
                if (v.id != R.id.cl_left && v.id != R.id.cl_right) {
                    return@singleClick
                }

                val item = mAdapter.getItem(position)
                if (item.userId == UserManager.getUserId()) {
                    item.luckyBagId?.let { mViewModel.gotoDetailLuckyBag(it) }
                } else {
                    val message = item.getBagMessage()
                        ?: return@singleClick
                    if (message.status == CommonConst.LuckyBagStatus.RECEIVING) {
                        item.luckyBagId?.let { mViewModel.receiveLuckyBag(it, message.coins) }
                    } else {
                        //自己领取过
                        if (message.receiveStatus.toBoolean()) {
                            item.luckyBagId?.let { mViewModel.gotoDetailLuckyBag(it) }
                        } else if (message.status == CommonConst.LuckyBagStatus.EXPIRED) {
                            ToastGravity.showGravity(string.lucky_bag_expired)
                        } else {
                            ToastGravity.showGravity(string.you_come_to_late)
                        }
                    }
                }
            }
        }
        mAdapter.setOnItemClickListener { _, _, position ->
            DebounceHelper.singleClick {
                val item = mAdapter.getItem(position)
                if (item.messageType != CommonConst.LuckyBagMessageType.RECEIVE) {
                    return@singleClick
                }

                item.luckyBagId?.let { mViewModel.gotoDetailLuckyBag(it) }
            }
        }

        mBinding.rvRecycler.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                mScrollState = newState
                if (mScrollState == RecyclerView.SCROLL_STATE_IDLE && isShowLastPosition()) {
                    mBinding.llGoTo.visibility = View.GONE
                }
            }
        })
        mBinding.llGoTo.setOnSingleClickListener {
            mBinding.llGoTo.visibility = View.GONE
            mBinding.rvRecycler.scrollToPosition(0)
        }
    }

    override fun initData() {
        mViewModel.onRefresh()
    }

    private fun updateState(resp: LuckyBagMessageResp) {
        val promptMessage = resp.getPromptMessage()
            ?: return

        resp.luckyBagId?.let { updateState(it, promptMessage.receiveCompleted == true) }
    }

    private fun updateState(resp: LuckyBagDetailResp) {
        updateState(resp.luckyBagId, resp.amount == resp.receiveCount)
    }

    private fun updateState(luckyBagId: Long, receiveCompleted: Boolean) {
        updateState(luckyBagId, 1, if (receiveCompleted) CommonConst.LuckyBagStatus.COMPLETED else null)
    }

    private fun updateState(luckyBagId: Long, receiveStatus: Int?, status: Int?) {
        //根据状态修改本地数据
        val position = mAdapter.data.indexOfFirst {
            it.messageType == CommonConst.LuckyBagMessageType.LUCKY_BAG
                    && it.luckyBagId == luckyBagId
        }
        if (position != -1) {
            val message = mAdapter.getItem(position)

            message.getBagMessage()?.let {
                val newBagMessage = it.copy(
                    receiveStatus = receiveStatus ?: it.receiveStatus,
                    status = status ?: it.status
                )

                message.updateBagMessage(newBagMessage)
                message.content = JsonUtils.toJson(newBagMessage)
                mAdapter.notifyItemChanged(position)
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onMessageEvent(message: LuckyBagNoticeMessage) {
        mViewModel.resolveNoticeMessage(message)
    }

    override fun onDestroy() {
        super.onDestroy()

        EventBus.getDefault().unregister(this)
    }

    fun isShowLastPosition(): Boolean {
        if (!isCreated()) return true
        val position = mBinding.rvRecycler.getFirstPosition() ?: 0
        return mScrollState == RecyclerView.SCROLL_STATE_IDLE && position < 2
    }

    companion object {

        const val ALL = 0          //全部消息
        const val CLAIMABLE = 1    //可领取的消息
        const val CHAT = 2         //聊天消息
    }
}